import { resolve } from 'path'
import { UserConfigExport, ConfigEnv, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import { viteMockServe } from 'vite-plugin-mock'
import svgLoader from 'vite-svg-loader'
import { wrapperEnv, regExps } from './build'
import ip from 'ip'
import liveReload from 'vite-plugin-live-reload'
import legacy from '@vitejs/plugin-legacy'
import { visualizer } from 'rollup-plugin-visualizer'
import fixElementPlus from './build/vite-fix-element-plus/plugin'
import viteImagemin from 'vite-plugin-imagemin'
import viteCompression from 'vite-plugin-compression'
import VueSetupExtend from 'vite-plugin-vue-setup-extend'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import WindiCSS from 'vite-plugin-windicss'
import { createStyleImportPlugin } from 'vite-plugin-style-import'

// 获取ip地址
const ipStr = ip.address()
// 路径查找
const pathResolve = (dir: string): string => {
  return resolve(__dirname, dir)
}
// 当前执行node命令时文件夹的地址（工作目录）
const root: string = process.cwd()
// https://vitejs.dev/config/
export default ({ command, mode }: ConfigEnv): UserConfigExport => {
  const { VITE_PORT, VITE_OUTDIR, VITE_PUBLIC_PATH, VITE_PROXY_API_PATH, VITE_BASE_API_PATH, VITE_LEGACY } = wrapperEnv(loadEnv(mode, root))
  const prodMock = true
  // 获取当前执行命令事件
  const lifecycle = process.env.npm_lifecycle_event
  return {
    base: VITE_PUBLIC_PATH,
    root,
    // 开发服务
    server: {
      https: false,
      port: VITE_PORT,
      host: ipStr,
      hmr: true,
      // 本地跨域代理
      proxy:
        VITE_BASE_API_PATH.length > 0
          ? {
              [VITE_PROXY_API_PATH]: {
                target: VITE_BASE_API_PATH,
                changeOrigin: true,
                rewrite: (path: string) => regExps(path, VITE_PROXY_API_PATH)
              }
            }
          : null,
      open: `http://${ipStr}:${VITE_PORT}`
    },
    // 生产环境配置
    build: {
      outDir: VITE_OUTDIR,
      assetsDir: 'assets/images',
      sourcemap: false,
      brotliSize: false,
      reportCompressedSize: false,
      // 消除打包大小超过500kb警告
      chunkSizeWarningLimit: 1024,
      minify: 'terser',
      target: 'esnext',
      // 清除console和debugger
      terserOptions: {
        compress: {
          drop_console: true,
          drop_debugger: true
        }
      },
      rollupOptions: {
        output: {
          chunkFileNames: (chunkInfo) => {
            const facadeModuleId = chunkInfo.facadeModuleId ? chunkInfo.facadeModuleId.split('/') : []
            let fileName = ''
            if (facadeModuleId.length > 0 && facadeModuleId[facadeModuleId.length - 1] === 'index.vue') {
              const index = facadeModuleId.indexOf('views')
              const idx = facadeModuleId.indexOf('src')
              if (idx > 0) {
                if (index > 0) {
                  fileName = 'vk_' + facadeModuleId.slice(index + 1, facadeModuleId.length - 1).join('_')
                } else {
                  fileName = 'vk_' + facadeModuleId.slice(idx + 1, facadeModuleId.length - 1).join('_')
                }
              } else {
                fileName = 'vk_[name]'
              }
            } else {
              fileName = 'vk_[name]'
            }
            return `assets/js/${fileName}-[hash].js`
          },
          entryFileNames: (chunkInfo) => {
            return 'assets/js/vk_[name]-[hash].js'
          },
          assetFileNames: (assetInfo) => {
            return 'assets/[ext]/vk_[name]-[hash].[ext]'
          },
          manualChunks(id) {
            if (id.includes('node_modules')) {
              const currentPlugin = id.toString().split('node_modules/')[1].split('/')[0].toString()
              if (
                currentPlugin === 'element-plus' ||
                currentPlugin === '@element-plus' ||
                currentPlugin === 'lodash-es' ||
                currentPlugin === '@vue' ||
                currentPlugin === 'china-area-data' ||
                currentPlugin === 'jsencrypt' ||
                currentPlugin === 'crypto-js' ||
                currentPlugin === 'xe-utils' ||
                currentPlugin === 'zrender' ||
                currentPlugin === 'echarts'
              ) {
                return currentPlugin
              } else if (currentPlugin === '@iconify') {
                const iconType = id.toString().split('node_modules/')[1].split('/')[3].split('.')[0].toString()
                return currentPlugin + '_' + iconType
              } else {
                return '_vendor'
              }
            } else {
              if (id.includes('/hooks/charts/mapCharts/map/')) {
                const currentPlugin = id.toString().split('/hooks/charts/mapCharts/map/')[1].split('.')[0].toString()
                return currentPlugin
              }
            }
          }
        }
      }
    },
    plugins: [
      vue(),
      // 解决某些文件修改后无法进行热更新，页面不会自动刷新问题
      liveReload(['src/layout/**/*', 'src/router/**/*']),
      svgLoader(),
      fixElementPlus(),
      VueSetupExtend(),
      WindiCSS(),
      createStyleImportPlugin({
        resolves: []
      }),
      Components({
        dirs: ['src/components', 'src/layout/components'],
        resolvers: [ElementPlusResolver()],
        // directoryAsNamespace: false, // 允许子文件夹名作为组件名的前缀
        // exclude: [/[\\/]src[\\/]components[\\/]pageDesigner[\\/]components[\\/]/],
        dts: 'types/components.d.ts' // 生成 `components.d.ts` 全局声明
      }),
      AutoImport({
        imports: ['vue', 'vue-router'], // 自动导入vue和vue-router相关函数
        // eslint报错解决
        eslintrc: {
          enabled: false, // Default `false`
          filepath: './.eslintrc-auto-import.json', // Default `./.eslintrc-auto-import.json`
          globalsPropValue: true // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable')
        },
        resolvers: [ElementPlusResolver()],
        dts: 'types/auto-import.d.ts' // 生成 `auto-import.d.ts` 全局声明
      }),
      viteMockServe({
        mockPath: './mock', // 模拟接口api文件存放的文件夹
        watchFiles: true, // 将监视文件夹中的文件更改。 并实时同步到请求结果
        localEnabled: command === 'serve' // ,设置是否启用本地 xxx.ts 文件，不要在生产环境中打开它.设置为 false 将禁用 mock 功能
        // prodEnabled: command !== 'serve' && prodMock, // 设置生产环境是否启用 mock 功能
        // injectCode: `
        //   import { setupProdMockServer } from './mockProdServer';
        //   setupProdMockServer();
        // `, // 如果生产环境开启了mock功能，该代码会注入到injectFile对应的文件的底部，默认为main.{ts,js}
        // injectFile: resolve(process.cwd(), 'src/main.{ts,js}'),
        // logger: true
      }),
      // 是否为打包后的文件提供传统浏览器兼容性支持(vue3本身不支持ie11，所以vite虽然能为支持ie11的语言做兼容性支持，但不能为vue3做兼容性支持)
      VITE_LEGACY
        ? legacy({
            targets: ['defaults', 'not IE 11', 'Android >= 4.4', 'iOS >= 9'], // 这里可以设置多个浏览器内核版本，使用vue3的情况下，设置ie11的兼容性也不会起作用。
            modernPolyfills: true
            // targets: ['ie >= 11','chrome >= 52'], // 这里可以设置多个浏览器内核版本，使用vue3的情况下，设置ie11的兼容性也不会起作用。
            // additionalLegacyPolyfills: ['regenerator-runtime/runtime'] // 面向ie11时需要此插件
          })
        : null,
      // 打包分析
      lifecycle === 'report' ? visualizer({ open: true, brotliSize: true, filename: VITE_OUTDIR + '/report.html' }) : null,
      viteImagemin({
        gifsicle: {
          optimizationLevel: 7,
          interlaced: false
        },
        optipng: {
          optimizationLevel: 7
        },
        webp: {
          quality: 75
        },
        mozjpeg: {
          quality: 65
        },
        pngquant: {
          quality: [0.65, 0.9],
          speed: 4
        },
        svgo: {
          plugins: [
            {
              removeViewBox: false
            },
            {
              removeEmptyAttrs: false
            }
          ]
        }
      })
      // viteCompression({
      //   verbose: true,
      //   disable: false, // 不禁用压缩
      //   deleteOriginFile: false, // 压缩后是否删除原文件
      //   threshold: 10240, // 压缩前最小文件大小
      //   algorithm: 'gzip', // 压缩算法
      //   ext: '.gz' // 文件类型
      // })
    ],
    // 依赖预构建，优化依赖
    optimizeDeps: {
      include: ['lodash-es', '@vueuse/core', '@vueuse/shared', 'element-plus/dist/locale/en.mjs', 'element-plus/dist/locale/zh-cn.mjs', 'element-plus/dist/locale/zh-tw.mjs']
    },
    resolve: {
      alias: {
        '@': pathResolve('src'),
        '^': pathResolve('build'),
        '#': pathResolve('types'),
        'vue-i18n': 'vue-i18n/dist/vue-i18n.cjs.js'
      }
    },
    css: {
      // css预处理器
      preprocessorOptions: {
        scss: {
          // 引入 var.scss 这样就可以在全局中使用 var.scss中预定义的变量了
          // 给导入的路径最后加上
          additionalData: `@use '@/style/var.scss' as *;`
        }
      }
    }
  }
}
